package com.gitee.wsl.struct.grammar.parser.tokenizer

import com.gitee.wsl.struct.grammar.parser.token.Token


/**
 * A Filter for the lexer, useful for filtering (e.g.) insignificant newlines. The accept function
 * is not just a parameter but needs to be overridden in a subclass as it's expected to be stateful.
 */
abstract class Filter(val filtered: Iterator<Token>) : Iterator<Token> {
    private var accepted: Token? = null

    /** Override this method to filter out specific tokens from the stream */
    abstract fun accept(token: Token): Boolean

    override fun hasNext(): Boolean {
        while (accepted == null && filtered.hasNext()) {
            val candidate = filtered.next()
            if (accept(candidate)) {
                accepted = candidate
            }
        }
        return accepted != null
    }

    override fun next(): Token{
        require (hasNext()) { "End of stream reached." }
        val result = accepted!!
        accepted = null
        return result
    }
}